package de.doegel.common;

import java.util.List;
import java.util.Vector;

import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.TextView;

import com.makeramen.segmented.SegmentedRadioGroup;

import de.doegel.common.model.Contact;
import de.doegel.common.ormlite.OrmLiteGDActivity;
import de.doegel.common.util.ImageDownloader;
import de.doegel.common.util.TextAndProgressBarUtils;
import de.doegel.common.util.Utils;
import de.doegel.common.widget.HeadedContactItem;
import de.doegel.common.widget.HeadedContactItemAdapter;

public class ContactSearchActivity<H extends AbstractDatabaseHelper> extends OrmLiteGDActivity<H>
{
	private final ImageDownloader	imageDownloader	= new ImageDownloader();

	public class ContactSearchListAdapter extends BaseAdapter
	{
		protected Context		context;
		protected List<Contact>	all;

		public ContactSearchListAdapter( Context context , List<Contact> all )
		{
			this.context = context;
			this.all = all;
		}

		public int getCount()
		{
			return all.size();
		}

		public Contact getItem( int position )
		{
			return all.get(position);
		}

		public long getItemId( int position )
		{
			return position;
		}

		public boolean isEnabled( int position )
		{
			return true;
		}

		public List<Contact> getContacts()
		{
			return all;
		}

		public View getView( int position , View convertView , ViewGroup parent )
		{
			View res = convertView;
			if (res == null)
				res = LayoutInflater.from(context).inflate(R.layout.contact_search_item, null);

			TextView contactNameText = (TextView) res.findViewById(R.id.contact_name);
			TextView contactLocationText = (TextView) res.findViewById(R.id.contact_location);
			ImageView contactImage = (ImageView) res.findViewById(R.id.contact_image);

			Contact contact = getItem(position);

			contactNameText.setText(contact.name);
			contactLocationText.setText(contact.location + ", " + contact.zipcode);

			contactImage.setImageResource(R.drawable.empty_contact_image);
			imageDownloader.download(contact.imageURL, contactImage);

			return res;
		}
	}

	private boolean						pickingContact				= false;

	private boolean						launchedFromMainActivity	= false;

	private SegmentedRadioGroup			radiogroup;
	private EditText					searchText;
	private ListView					listview;
	private View						textandprogressbar			= null;

	private HeadedContactItemAdapter	localContactsAdapter;
	private ContactSearchListAdapter	allContactsAdapter;

	private FetchContactsTask			currentTask					= null;

	private TextWatcher					filterTextWatcher			= new TextWatcher()
																	{
																		@Override
																		public void onTextChanged( CharSequence s , int start , int before , int count )
																		{
																			if (radiogroup.getCheckedRadioButtonId() == R.id.contact_type_local)
																			{
																				if (localContactsAdapter != null)
																				{
																					localContactsAdapter.getFilter().filter(s);
																				}
																			}
																		}

																		@Override
																		public void beforeTextChanged( CharSequence s , int start , int count , int after )
																		{
																		}

																		@Override
																		public void afterTextChanged( Editable s )
																		{
																		}
																	};

	@Override
	public void onCreate( Bundle savedInstanceState )
	{
		super.onCreate(savedInstanceState);
		setActionBarContentView(R.layout.contact_search);

		Bundle extras = getIntent().getExtras();
		if (extras != null)
		{
			pickingContact = extras.getBoolean(IDoegelConstants.PICK_CONTACT_EXTRA);
			launchedFromMainActivity = extras.getBoolean(IDoegelConstants.LAUNCHED_FROM_MAIN_ACTIVITY_EXTRA);
		}

		setTitle(pickingContact ? R.string.pick_contact_activity_title : R.string.contact_search_activity_title);

		searchText = (EditText) findViewById(R.id.search_text);
		searchText.setOnEditorActionListener(new TextView.OnEditorActionListener()
		{
			@Override
			public boolean onEditorAction( TextView v , int actionId , KeyEvent event )
			{
				if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_NULL)
				{
					InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
					imm.hideSoftInputFromWindow(searchText.getWindowToken(), 0);

					searchContacts();
					return true;
				}
				return false;
			}
		});
		searchText.addTextChangedListener(filterTextWatcher);

		listview = (ListView) findViewById(R.id.list);

		textandprogressbar = getLayoutInflater().inflate(R.layout.text_and_progressbar, listview, false);
		listview.addFooterView(textandprogressbar, null, false);
		TextAndProgressBarUtils.initializeTextAndProgressBar(listview, textandprogressbar);

		listview.setOnItemClickListener(new OnItemClickListener()
		{
			@Override
			public void onItemClick( AdapterView<?> parent , View view , int position , long id )
			{
				Contact contact = null;
				Object item = parent.getAdapter().getItem(position);
				if (item instanceof HeadedContactItem)
				{
					contact = (Contact) ((HeadedContactItem) item).getTag();
				}
				else
				{
					contact = (Contact) item;
				}
				if (contact != null)
				{
					if (pickingContact)
					{
						Intent intent = new Intent();
						intent.putExtra(IDoegelConstants.PERSON_ID_EXTRA, contact.id);
						intent.putExtra(IDoegelConstants.PERSON_NAME_EXTRA, contact.name);
						if (ContactSearchActivity.this.getParent() == null)
						{
							ContactSearchActivity.this.setResult(RESULT_OK, intent);
						}
						else
						{
							ContactSearchActivity.this.getParent().setResult(RESULT_OK, intent);
						}
						ContactSearchActivity.this.finish();
					}
					else
					{
						startActivity(Utils.createPersonIntent(ContactSearchActivity.this, contact.id, contact.name));
					}
				}
			}
		});

		radiogroup = (SegmentedRadioGroup) findViewById(R.id.contact_type);
		radiogroup.setOnCheckedChangeListener(new OnCheckedChangeListener()
		{
			public void onCheckedChanged( RadioGroup group , int checkedId )
			{
				changeContactsList();
			}
		});

		localContactsAdapter = null;
		allContactsAdapter = new ContactSearchListAdapter(ContactSearchActivity.this, new Vector<Contact>());

		changeContactsList();

		new ReadContactsFromDBTask().execute();
	}

	@Override
	public void onDestroy()
	{
		searchText.removeTextChangedListener(filterTextWatcher);
		super.onDestroy();
	}

	public void changeContactsList()
	{
		if (currentTask != null)
		{
			currentTask.cancel(true);
			currentTask = null;
		}

		if (radiogroup.getCheckedRadioButtonId() == R.id.contact_type_local)
		{
			if (localContactsAdapter == null)
			{
				TextAndProgressBarUtils.showTextAndProgressBar(listview);
				TextAndProgressBarUtils.configureTextAndProgressBar(listview, null, false, true);
			}
			else
			{
				if (localContactsAdapter.getCount() == 0)
				{
					TextAndProgressBarUtils.showTextAndProgressBar(listview);
					TextAndProgressBarUtils.configureTextAndProgressBar(listview, getString(R.string.contacts_empty), false, false);
				}
				else
				{
					TextAndProgressBarUtils.hideTextAndProgressBar(listview);
				}
			}
			listview.setAdapter(localContactsAdapter);
		}
		else
		{
			TextAndProgressBarUtils.hideTextAndProgressBar(listview);
			allContactsAdapter.getContacts().clear();
			listview.setAdapter(allContactsAdapter);
		}

		searchText.setText("");
	}

	public void searchContacts()
	{
		if (currentTask == null && radiogroup.getCheckedRadioButtonId() == R.id.contact_type_all)
		{
			if (!TextUtils.isEmpty(searchText.getText().toString()))
			{
				currentTask = new FetchContactsTask(true);
				currentTask.execute(searchText.getText().toString());
			}
		}
	}

	@Override
	public boolean onKeyUp( int keyCode , KeyEvent event )
	{
		if (keyCode == KeyEvent.KEYCODE_SEARCH)
		{
			if (currentTask == null && radiogroup.getCheckedRadioButtonId() == R.id.contact_type_all)
			{
				if (!TextUtils.isEmpty(searchText.getText().toString()))
				{
					currentTask = new FetchContactsTask(true);
					currentTask.execute(searchText.getText().toString());
				}
			}
		}
		return super.onKeyUp(keyCode, event);

	}

	public void onTextAndProgressBarClick( View view )
	{
		new FetchContactsTask(false).execute(searchText.getText().toString());
	}

	private class ReadContactsFromDBTask extends AsyncTask<Void, Void, List<HeadedContactItem>>
	{
		@Override
		protected List<HeadedContactItem> doInBackground( Void... params )
		{
			return Utils.createItems(getHelper());
		}

		@Override
		protected void onPostExecute( List<HeadedContactItem> result )
		{
			localContactsAdapter = new HeadedContactItemAdapter(ContactSearchActivity.this, result, IDoegelConstants.SECTIONS);
			changeContactsList();
			super.onPostExecute(result);
		}
	}

	private class FetchContactsTask extends AsyncTask<String, Void, List<Contact>>
	{
		private boolean	newSearch;

		public FetchContactsTask( boolean newSearch )
		{
			this.newSearch = newSearch;
		}

		@Override
		protected void onPreExecute()
		{
			if (newSearch)
			{
				allContactsAdapter.getContacts().clear();
				listview.invalidateViews();
			}
			TextAndProgressBarUtils.showTextAndProgressBar(listview);
			TextAndProgressBarUtils.configureTextAndProgressBar(listview, null, false, true);
		}

		@Override
		protected List<Contact> doInBackground( String... params )
		{
			String searchString = params[0];
			return ((DoegelApplication) getApplication()).getHttpConnector().searchContacts(ContactSearchActivity.this, searchString, newSearch ? 0 : allContactsAdapter.getContacts().size());
		}

		@Override
		protected void onPostExecute( List<Contact> result )
		{
			if (!isCancelled())
			{
				if (result != null)
				{
					allContactsAdapter.getContacts().addAll(result);
					listview.invalidateViews();

					if (newSearch)
					{
						if (result.size() == 0)
						{
							TextAndProgressBarUtils.configureTextAndProgressBar(listview, getString(R.string.search_nothing), false, false);
						}
						else if (result.size() < 25)
						{
							TextAndProgressBarUtils.configureTextAndProgressBar(listview, getString(R.string.search_nomore), false, false);
						}
						else
						{
							TextAndProgressBarUtils.configureTextAndProgressBar(listview, getString(R.string.search_more), true, false);
						}
					}
					else
					{
						if (result.size() < 25)
						{
							TextAndProgressBarUtils.configureTextAndProgressBar(listview, getString(R.string.search_nomore), false, false);
						}
						else
						{
							TextAndProgressBarUtils.configureTextAndProgressBar(listview, getString(R.string.search_more), true, false);
						}
					}
				}
				else
				{
					TextAndProgressBarUtils.configureTextAndProgressBar(listview, getString(R.string.network_problem), false, false);
					//TextAndProgressBarUtils.configureTextAndProgressBar(listview, getString(R.string.search_nothing), false, false);
				}
			}

			currentTask = null;

			super.onPostExecute(result);
		}
	}

	private static final int	CONTEXT_MENU_HOME		= 0;
	private static final int	CONTEXT_MENU_SETTINGS	= 1;
	private static final int	CONTEXT_MENU_SEARCH		= 2;

	@Override
	public boolean onCreateOptionsMenu( Menu menu )
	{
		menu.add(0, CONTEXT_MENU_HOME, 0, R.string.home_context_menu);
		if (launchedFromMainActivity)
		{
			menu.add(0, CONTEXT_MENU_SETTINGS, 0, R.string.settings_context_menu);
		}
		menu.add(0, CONTEXT_MENU_SEARCH, 0, R.string.search_context_menu);
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onPrepareOptionsMenu( Menu menu )
	{
		return super.onPrepareOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected( MenuItem item )
	{
		switch (item.getItemId())
		{
			case CONTEXT_MENU_HOME:
				startActivity(Utils.createHomeIntent(this));
				return true;
			case CONTEXT_MENU_SETTINGS:
				startActivity(Utils.createSettingsIntent(this));
				finish();
				return true;
			case CONTEXT_MENU_SEARCH:
				searchContacts();
				return true;
			default:
				return super.onOptionsItemSelected(item);
		}
	}
}